using B.S.XZYData.Api.Read.Application.Command.WorkOrder;
using B.S.XZYData.Domain.LJC;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.XZYData.Api.Read.Application.Handler.WorkOrder
{
    /// <summary>
    /// 导出工单处理器
    /// </summary>
    public class ExportWorkOrderHandler : IRequestHandler<ExportWorkOrderCommand, ApiResult<byte[]>>
    {
        private readonly IBaseRepository<WorkOrderModel> _workOrderRepo;
        private readonly ILogger<ExportWorkOrderHandler> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="workOrderRepo">工单仓储</param>
        /// <param name="logger">日志记录器</param>
        public ExportWorkOrderHandler(
            IBaseRepository<WorkOrderModel> workOrderRepo,
            ILogger<ExportWorkOrderHandler> logger)
        {
            _workOrderRepo = workOrderRepo;
            _logger = logger;
        }

        /// <summary>
        /// 导出工单
        /// </summary>
        /// <param name="request">导出命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>返回Excel文件字节数组</returns>
        public async Task<ApiResult<byte[]>> Handle(ExportWorkOrderCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<byte[]>();

            try
            {
                // 构建查询条件
                var query = _workOrderRepo.GetAll();

                // 工单编号
                if (!string.IsNullOrWhiteSpace(request.Code))
                {
                    query = query.Where(x => x.Code != null && x.Code.Contains(request.Code));
                }

                // 产品编号
                if (!string.IsNullOrWhiteSpace(request.ProductCode))
                {
                    query = query.Where(x => x.ProductCode != null && x.ProductCode.Contains(request.ProductCode));
                }

                // 产品名称
                if (!string.IsNullOrWhiteSpace(request.ProductName))
                {
                    query = query.Where(x => x.ProductName != null && x.ProductName.Contains(request.ProductName));
                }

                // 规格
                if (!string.IsNullOrWhiteSpace(request.Spec))
                {
                    query = query.Where(x => x.Spec != null && x.Spec.Contains(request.Spec));
                }

                // 单位
                if (!string.IsNullOrWhiteSpace(request.Unit))
                {
                    query = query.Where(x => x.Unit != null && x.Unit.Contains(request.Unit));
                }

                // 实际数量
                if (request.ActualQuantity.HasValue)
                {
                    query = query.Where(x => x.ActualQuantity == request.ActualQuantity.Value);
                }

                // 状态
                if (!string.IsNullOrWhiteSpace(request.Status))
                {
                    query = query.Where(x => x.Status == request.Status);
                }

                // 创建人
                if (!string.IsNullOrWhiteSpace(request.CreateBy))
                {
                    query = query.Where(x => x.CreateBy != null && x.CreateBy.Contains(request.CreateBy));
                }

                // 计划开始时间范围
                if (request.PlannedStartTimeStart.HasValue)
                {
                    query = query.Where(x => x.PlannedStartTime >= request.PlannedStartTimeStart.Value);
                }
                if (request.PlannedStartTimeEnd.HasValue)
                {
                    query = query.Where(x => x.PlannedStartTime <= request.PlannedStartTimeEnd.Value);
                }

                // 计划结束时间范围
                if (request.PlannedEndTimeStart.HasValue)
                {
                    query = query.Where(x => x.PlannedEndTime >= request.PlannedEndTimeStart.Value);
                }
                if (request.PlannedEndTimeEnd.HasValue)
                {
                    query = query.Where(x => x.PlannedEndTime <= request.PlannedEndTimeEnd.Value);
                }

                // 实际开始时间范围
                if (request.ActualStartTimeStart.HasValue)
                {
                    query = query.Where(x => x.ActualStartTime >= request.ActualStartTimeStart.Value);
                }
                if (request.ActualStartTimeEnd.HasValue)
                {
                    query = query.Where(x => x.ActualStartTime <= request.ActualStartTimeEnd.Value);
                }

                // 实际结束时间范围
                if (request.ActualEndTimeStart.HasValue)
                {
                    query = query.Where(x => x.ActualEndTime >= request.ActualEndTimeStart.Value);
                }
                if (request.ActualEndTimeEnd.HasValue)
                {
                    query = query.Where(x => x.ActualEndTime <= request.ActualEndTimeEnd.Value);
                }

                // 创建时间范围
                if (request.CreateTimeStart.HasValue)
                {
                    query = query.Where(x => x.CreateTime >= request.CreateTimeStart.Value);
                }
                if (request.CreateTimeEnd.HasValue)
                {
                    query = query.Where(x => x.CreateTime <= request.CreateTimeEnd.Value);
                }

                // 执行查询
                var workOrders = query.OrderByDescending(x => x.CreateTime).ToList();

                // 生成CSV文件内容
                var csvContent = GenerateCsvContent(workOrders);
                var csvBytes = Encoding.UTF8.GetBytes(csvContent);

                // 添加BOM以支持中文
                var bom = Encoding.UTF8.GetPreamble();
                var result = new byte[bom.Length + csvBytes.Length];
                bom.CopyTo(result, 0);
                csvBytes.CopyTo(result, bom.Length);

                res.Data = result;
                res.Code = ApiEnum.Success;
                res.Msg = $"导出成功，共{workOrders.Count}条记录";

                _logger.LogInformation($"导出工单成功，导出{workOrders.Count}条记录");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出工单失败");
                res.Code = ApiEnum.Error;
                res.Msg = $"导出工单失败：{ex.Message}";
            }

            return res;
        }

        /// <summary>
        /// 生成CSV内容
        /// </summary>
        /// <param name="workOrders">工单列表</param>
        /// <returns>CSV内容</returns>
        private string GenerateCsvContent(List<WorkOrderModel> workOrders)
        {
            var csv = new StringBuilder();

            // CSV标题行
            csv.AppendLine("工单编号,产品编号,产品名称,规格,单位,计划数量,实际数量,合格数量,不合格数量,状态,计划开始时间,计划结束时间,实际开始时间,实际结束时间,备注,创建人,创建时间,更新人,更新时间");

            // 数据行
            foreach (var item in workOrders)
            {
                csv.AppendLine($"\"{EscapeCsvValue(item.Code)}\"," +
                              $"\"{EscapeCsvValue(item.ProductCode)}\"," +
                              $"\"{EscapeCsvValue(item.ProductName)}\"," +
                              $"\"{EscapeCsvValue(item.Spec)}\"," +
                              $"\"{EscapeCsvValue(item.Unit)}\"," +
                              $"{item.PlannedQuantity}," +
                              $"{item.ActualQuantity}," +
                              $"{item.GoodQuantity}," +
                              $"{item.BadQuantity}," +
                              $"\"{EscapeCsvValue(item.Status)}\"," +
                              $"\"{FormatDateTime(item.PlannedStartTime)}\"," +
                              $"\"{FormatDateTime(item.PlannedEndTime)}\"," +
                              $"\"{FormatDateTime(item.ActualStartTime)}\"," +
                              $"\"{FormatDateTime(item.ActualEndTime)}\"," +
                              $"\"{EscapeCsvValue(item.Remark)}\"," +
                              $"\"{EscapeCsvValue(item.CreateBy)}\"," +
                              $"\"{FormatDateTime(item.CreateTime)}\"," +
                              $"\"{EscapeCsvValue(item.UpdateBy)}\"," +
                              $"\"{FormatDateTime(item.UpdateTime)}\"");
            }

            return csv.ToString();
        }

        /// <summary>
        /// 转义CSV值
        /// </summary>
        /// <param name="value">原始值</param>
        /// <returns>转义后的值</returns>
        private string EscapeCsvValue(string value)
        {
            if (string.IsNullOrEmpty(value))
                return "";

            // 替换双引号为两个双引号
            return value.Replace("\"", "\"\"");
        }

        /// <summary>
        /// 格式化日期时间
        /// </summary>
        /// <param name="dateTime">日期时间</param>
        /// <returns>格式化后的字符串</returns>
        private string FormatDateTime(DateTime? dateTime)
        {
            return dateTime?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";
        }
    }
}
